package dyyx.demo;
import java.sql.Connection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import dyyx.util.CommUtil;
import dyyx.util.JdbcUtil;

public class H2ReadWriteTest {
	
	
	private static final String TABLE = System.getProperty("table", "test01");
	private static final int MAXID = CommUtil.getIntFromSystemProp("maxid", 1000000);
	private static final int MAX_NAME_SEQ = CommUtil.getIntFromSystemProp("maxNameSeq", 10000000);

	private static final Random RANDOM = new Random();
	
	private static final Map<String,AtomicLong> countMap = new ConcurrentHashMap<String,AtomicLong>();
	private static final Map<String,String> errorMap = new ConcurrentHashMap<String,String>();

	
	public static void main(String[] args) throws Exception {
		System.out.println("hello,H2ReadWriteTest,"+new Date());
		// test();
		
		InsertThread insertThread = new InsertThread();
		UpdateThread updateThread = new UpdateThread();
		QueryThread queryThread = new QueryThread();
		DeleteThread deleteThread = new DeleteThread();
		
		insertThread.setName("insertThread");
		updateThread.setName("updateThread");
		queryThread.setName("queryThread");
		deleteThread.setName("deleteThread");


		insertThread.start();
		queryThread.start();
		updateThread.start();
		deleteThread.start();

		while(true){
			Thread.sleep(3000);
			info();
			
		}

	}
	
	private static void info(){
		Map map = new HashMap();
		map.put("table", TABLE);
		map.put("MAXID", MAXID);
		map.put("MAX_NAME_SEQ", MAX_NAME_SEQ);
		
		System.out.println(map+","+countMap+","+errorMap);


	}
	

	private static void incr(String key){
		AtomicLong al = countMap.get(key);
		if(al==null){
			al = new AtomicLong(0);
			countMap.put(key, al);
		}
		al.getAndIncrement();
	}
	
	
	private static int genID(){
		return RANDOM.nextInt(MAXID);
	}
	
	private static String genName(){
		return "name_"+RANDOM.nextInt(MAX_NAME_SEQ);
	}
	
	private static int genAge(){
		return 1+RANDOM.nextInt(100);
	}
	
	
	private static String queryNameById(Connection cn,int id)throws Exception{
		String sql = "select name from "+TABLE+" WHERE ID="+id;
		return JdbcUtil.queryAsString(cn, sql);
	}
	
	private static Map<String,String> queryById(Connection cn,int id)throws Exception{
		String sql = "select * from "+TABLE+" WHERE ID="+id;
		return JdbcUtil.queryOneAsMap(cn, sql);
	}
	
	
	
	private static int insert(Connection cn,int id,String name,int age)throws Exception{
		String sql = "insert into "+TABLE+"(id,name,age) values("+id+",'"+name+"',"+id+")";
		return JdbcUtil.update(cn, sql);
	}
	
	private static int update(Connection cn,int id,int age)throws Exception{
		String sql = "update "+TABLE+" set age="+age+" where id="+id;
		return JdbcUtil.update(cn, sql);
	}
	
	private static int delete(Connection cn,int id)throws Exception{
		String sql = "delete from  "+TABLE+" where id="+id;
		return JdbcUtil.update(cn, sql);
	}
	
	
	
	private static class InsertThread extends Thread{
		public void run(){
			Connection cn = null;
			
			try{
			    cn = JdbcUtil.getConn();
			}catch(Throwable e){
				System.out.println("InsertThread getConn error,"+e);
				return;
			}
			while(true){	
				int id = genID();
				String name = genName();
				int age = genAge();
				try{
				    insert(cn,id,name,age);
				    incr("insertOK");
				}catch(Throwable e){
				    incr("insertError");
                    errorMap.put("insertError", e.toString());
				}				
			}
			
		}
	}
	
	private static class UpdateThread extends Thread{
		public void run(){
			
            Connection cn = null;
			
			try{
			    cn = JdbcUtil.getConn();
			}catch(Throwable e){
				System.out.println("UpdateThread getConn error,"+e);
				return;
			}
			
			while(true){	
				int id = genID();
				// String name = genName();
				int age = genAge();
				try{
				    update(cn,id,age);
				    incr("updateOK");
				}catch(Throwable e){
				    incr("updateError");
                    errorMap.put("updateError", e.toString());
				}				
			}
			
		}
	}
	
	
	private static class QueryThread extends Thread{
		public void run(){
			
			  Connection cn = null;
				
				try{
				    cn = JdbcUtil.getConn();
				}catch(Throwable e){
					System.out.println("QueryThread getConn error,"+e);
					return;
				}
				
				while(true){	
					int id = genID();
					// String name = genName();
					// int age = genAge();
					try{
					    queryById(cn,id);
					    incr("queryOK");
					    
					    
					}catch(Throwable e){
					    incr("queryError");
	                    errorMap.put("queryError", e.toString());
					}				
				}
			
		}
	}
	
	

	private static class DeleteThread extends Thread{
		public void run(){
			Connection cn = null;
			
			try{
			    cn = JdbcUtil.getConn();
			}catch(Throwable e){
				System.out.println("DeleteThread getConn error,"+e);
				return;
			}
			
			while(true){	
				int id = genID();
				// String name = genName();
				// int age = genAge();
				try{
				    delete(cn,id);
				    incr("deleteOK");
				}catch(Throwable e){
				    incr("deleteError");
                    errorMap.put("deleteError", e.toString());
				}				
			}
		}
	}
	
	
	private static void test() throws Exception{
		int id = genID();
		String name = genName();
		int age = genAge();
		
		System.out.println(id+","+name+","+age);

		Connection cn = JdbcUtil.getConn();
		
		
		int result = delete(cn,id);
		System.out.println("delete result "+result);
		
		result = insert(cn,id,name,age);
		System.out.println("insert result "+result);
		
		System.out.println("query name "+queryNameById(cn,id));
		
		System.out.println(queryById(cn,id));


        int age2 = genAge();
		System.out.println("age2="+age2);
		
		result = update(cn,id,age);
		System.out.println("update result "+result);
		
		System.out.println(queryById(cn,id));


		result = delete(cn,id);
		System.out.println("delete result "+result);
		
		JdbcUtil.close(cn);
	}
	
	
}
